import com.bit.www.*;
/**
 * 类和对象
 * 1.封装
 * 2.static成员
 * 3.代码块
 */
class Student {
    private String name;
    private int age;

    private static String name2 = "lisi";//测试静态成员方法
    public static String className;//static修饰的成员变量

    public static String getClassName() {
        return className;
    }

    public static void setClassName(String className) {
        Student.className = className;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 关于成员变量的 get(获取) set(创建) 方法
     * @return
     * 快捷键: Alt + Insert
     * 点击: 右键 ->Generate + get/set(可以只选择set get一个,也可以全部选择)
     */
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat() {
        System.out.println(this.name + "正在吃饭...");
    }
    /**
     * 静态成员方法
     */
    public static void sleep() {
        System.out.println( name2 + "正在睡觉....");
    }
}

class StaticClass {
    //就地初始化
    public int num2;
    public static int num1 = 10;

    /**
     * 实例代码块,构造代码块
     */
    {
        num2 = 999;
        System.out.println("实例代码块被执行了...");
    }
    /**
     * 静态代码块
     */
    static  {
        num1 = 1000;
        System.out.println("静态代码块被执行了...");
    }
    /**
     * 构造方法
     */
    public StaticClass() {
        num2 = 666;
        System.out.println("构造方法被执行了....");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog("小黑",20,"黑色");

        dog.barks();
        dog.eat();
        Dog.staticFunc();
        System.out.println(dog.toString());
    }
    /**
     * static成员
     * 1.static修饰成员变量
     * 2.static修饰成员方法
     * 3.static成员变量初始化
     */
    public static void main9(String[] args) {
        /**
         * static成员变量初始化
         * 1.就地初始化
         * 2.静态代码块初始化
         *
         *
         *  代码块
         *  普通代码块(方法中的{}内表示的代码)
         *  构造代码块/实例代码块(定义在类中的代码块(类中{}包含的代码块)),一般用来初始化成员变量
         *  静态代码块:被static{}包含的代码,一般用来修饰static修饰的成员变量
         *
         *  注
         *  1.静态代码块不管创建多少个对象,都只执行一次
         *  2.静态代码块属于类,因此是在JVM加载时,开辟空间并进行初始化的
         *  3.出现多个静态代码块时,会进行合并,然后依次执行
         *  4.实例代码块,只有创建对象时,才会被执行
         */

        StaticClass staticClass = new StaticClass();

        System.out.println(StaticClass.num1);
        System.out.println(staticClass.num2);
        /**
         * 执行顺序
         * 1.静态代码块->类加载就执行静态代码块
         * 2.实例代码块->new时,执行实例代码块
         * 3.构造方法->随后执行构造方法进行初始化
         */
    }
    public static int staticNum = 100;
    public static void main8(String[] args) {
        Test test1 = new Test();
        test1.staticNum++;

        Test test2 = new Test();
        test1.staticNum++;

        Test test3 = new Test();
        test1.staticNum++;

        Test.staticNum++;

        System.out.println(staticNum);//102
    }
    public static void main7(String[] args) {
        /**
         * static修饰成员方法->静态成员方法()
         * 1.静态成员方法不属于任何对象,是类的方法
         * 2.可以通过对象访问方法,也可以使用类.静态成员方法进行访问,更推荐后者
         * 3.静态成员方法中,不能访问任何非静态成员变量()
         * 4.静态成员方法中,不能访问任何非静态成员方法(非静态成员方法,可以访问静态成员方法)
         * 本质,非静态成员方法有this参数,在静态成员方法中,无法调用
         */
        Student.sleep();
    }
    public static void main6(String[] args) {
        /**
         * static修饰成员变量->静态成员变量(变量只能是成员变量不能是局部变量)
         * 特性:1.不属于任何一个对象,是类的属性,每个对象共享
         * 2.既可以通过对象访问(不建议使用,会产生警告),也可以推荐类访问(建议使用)
         * 3.存储在方法区中
         * 4.随着类的加载而创建随着类的结束而销毁
         */
        Student student1 = new Student("张三",18);
        Student student2 = new Student("李四",20);
        Student student3 = new Student("王五",25);

        Student.className = "2114";

        System.out.println("姓名 " + student1.getName());
        System.out.println("姓名 " + student2.getName());
        System.out.println("姓名 " + student3.getName());

        System.out.println("上课教室 " + Student.getClassName());
    }
    /**
     * 封装
     * @param args
     * 1.封装的概念
     * 2.访问限定符
     * 3.拓展->包
     */

    /**
     * 包
     * 包的概念
     * 导入类中的包
     * 自定义包
     */
    public static void main4(String[] args) {
        /**
         * 导入类中的包
         * 1.使用import 导入包(例如 import java.util.Arrays)
         * 2.在进行使用时,直接路径.(这样子就不需要使用import进行导包)
         * 3.可以最后包名使用*(通配符),表示所有该路径下的包,不过不建议,可能导致和其他路径包发生歧义
         * 4.import static 进行导包,例如(import static java.util.Arrays),可以省略包名,直接使用包内方法.对象
         */
    }
    public static void main3(String[] args) {
        /**
         * 自定义包
         * 1.右键 + new  + package进行自定义包
         * 2.包名最好指定成唯一名字,一般为公司域名颠倒形式(com.baidu.www)
         * 3.包命名规则: 全小写
         * 4.包名要和代码路径相匹配(一般创建包后,就会自动生成路径用来存储代码)
         * 5.如果类中没有出现package语句,则证明代码放在默认包中
         */
    }

    public static void main2(String[] args) {
        /**
         * 包的概念:为了更好的管理类,将多个类收集成为一组,可以理解为文件夹
         * 包的重要性:可以使工程中,出现同名的类,只要在不同包即可
         */
    }
    public static void main5(String[] args) {
        /**
         * 访问限定符
         * private: 相同包 相同类
         * default(默认,当什么都不写时,为该限定):相同包 相同类 不同类,可以使用
         * protected:相同包中相同类 不同类,不同包中的子类
         * public(公共类): 工程中任意类内都使用
         */
    }
    public static void main1(String[] args) {
        /**
         * 封装的概念
         * 套壳屏蔽细节
         * 即使用访问限定符,来对成员变量,成员方法来进行限制()
         */
        Student student1 = new Student("张三",18);
//        student1.name = "李四";//error

        String name = student1.getName();//获取name
        System.out.println(name);

        student1.setName("李四");//通过类提供的创建(更改)name

        student1.eat();
    }
}
